use once_cell::sync::Lazy;
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct ServerConfig {
    ip: String,
    port: u16,
}

#[derive(Debug, Deserialize)]
struct Secret {
    secret: String,
}

#[derive(Debug, Deserialize)]
struct Db {
    mysql: String,
}

#[derive(Debug, Deserialize)]
pub struct Config {
    api_server: ServerConfig,
    grpc_server: ServerConfig,
    secret: Secret,
    db: Db,
}

impl Default for Config {
    fn default() -> Self {
        let config_content =
            std::fs::read_to_string("config.toml").expect("Failed to read config.toml");
        let config: Config = toml::from_str(&config_content).expect("Failed to parse TOML file");
        config
    }
}

impl Config {
    pub fn api_addr(&self) -> String {
        "".to_owned()
            + self.api_server.ip.as_str()
            + ":"
            + self.api_server.port.to_string().as_str()
    }

    pub fn volo_addr(&self) -> String {
        "".to_owned()
            + self.grpc_server.ip.as_str()
            + ":"
            + self.grpc_server.port.to_string().as_str()
    }

    pub fn secret(&self) -> String {
        self.secret.secret.to_owned()
    }

    pub fn mysql(&self) -> String {
        self.db.mysql.to_owned()
    }
}

pub static CONFIG: Lazy<Config> = Lazy::new(Config::default);
